package com.winit.openapi.oauth.manager.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.winit.common.orm.mybatis.PageBase;
import com.winit.common.query.Page;
import com.winit.common.query.SearchOperator;
import com.winit.common.query.Searchable;
import com.winit.common.query.Sort;
import com.winit.common.query.Sort.Direction;
import com.winit.common.query.filter.SearchFilterHelper;
import com.winit.openapi.constants.ErrorCode;
import com.winit.openapi.exception.ApiBizException;
import com.winit.openapi.oauth.command.QueryClientByDeveloperCommand;
import com.winit.openapi.oauth.dao.APIClientDao;
import com.winit.openapi.oauth.dao.APIDeveloperDao;
import com.winit.openapi.oauth.dao.UserAuthorizationDao;
import com.winit.openapi.oauth.entity.APIClientEntity;
import com.winit.openapi.oauth.entity.APIDeveloperEntity;
import com.winit.openapi.oauth.manager.APIClientManager;
import com.winit.openapi.oauth.vo.APIClientVo;
import com.winit.openapi.util.BeanUtils;

@Service("apiClientManager")
public class APIClientManagerImpl implements APIClientManager {

    private Logger               logger = LoggerFactory.getLogger(APIClientManagerImpl.class);

    @Resource
    private APIClientDao         apiClientDao;

    @Resource
    private APIDeveloperDao      apiDeveloperDao;

    @Resource
    private UserAuthorizationDao userAuthorizationDao;

    @Override
    @Transactional
    public int insertClient(APIClientVo vo) {

        try {
            APIClientEntity entity = BeanUtils.copyProperties(vo, APIClientEntity.class);
            if (entity == null) {
                return -1;
            }
            return apiClientDao.insertClient(entity);
        } catch (Exception e) {
            logger.error("添加应用异常,error:{}", e);
            throw new ApiBizException(ErrorCode.OAUTH_CREATE_CLIENT_ERROR);

        }
    }

    @Override
    public boolean checkExists(Long developerId, String clientName) {
        APIClientEntity entity = apiClientDao.selectByNameAndDeveloperId(developerId, clientName);

        return entity != null;
    }

    @Override
    public APIClientVo getById(Long clientId) {

        try {
            APIClientEntity entity = apiClientDao.selectById(clientId);
            if (null == entity) {
                return null;
            }
            return BeanUtils.copyProperties(entity, APIClientVo.class);
        } catch (Exception e) {
            logger.error("查询应用异常,error:{}", e);
            throw new ApiBizException(ErrorCode.OAUTH_CLIENT_QUERY_ERROR);
        }
    }

    @Override
    @Transactional
    public void updateClient(APIClientVo vo) {
        try {
            APIClientEntity entity = BeanUtils.copyProperties(vo, APIClientEntity.class);
            if (entity == null) {
                return;
            }

            apiClientDao.updateClient(entity);
            userAuthorizationDao.updateClient(entity.getId(), entity.getClientName());
        } catch (Exception e) {
            logger.error("更新应用异常,error:{}", e);
            throw new ApiBizException(ErrorCode.OAUTH_CLIENT_UPDATE_ERROR);
        }
    }

    @Override
    public List<APIClientVo> getByDeveloperAccount(String developerAccount) {
        try {
            APIDeveloperEntity developer = apiDeveloperDao.selectByAccount(developerAccount);
            if (developer == null) {
                logger.error("查询开发者失败,账号号：{}", developerAccount);
                return null;
            }
            List<APIClientEntity> list = apiClientDao.getByDeveloperId(developer.getId());
            if (CollectionUtils.isEmpty(list)) {
                return null;
            }
            return BeanUtils.copyList(list, APIClientVo.class);
        } catch (Exception e) {
            logger.error("根据账号查询应用失败", e);
            throw new ApiBizException(ErrorCode.OAUTH_CLIENT_QUERY_ERROR);
        }
    }

    @Override
    public APIClientVo selectByClientKey(String clientKey) {

        try {
            APIClientEntity entity = apiClientDao.selectByClientKey(clientKey);
            if (null == entity) {
                return null;
            }
            return BeanUtils.copyProperties(entity, APIClientVo.class);
        } catch (Exception e) {
            logger.error("查询应用异常,error:{}", e);
            throw new ApiBizException(ErrorCode.OAUTH_CLIENT_QUERY_ERROR);

        }
    }

    @Override
    public boolean checkLogin(String clientKey, String clientSrcret) {

        try {
            return null != apiClientDao.checkLogin(clientKey, clientSrcret);
        } catch (Exception e) {
            logger.error("查询应用异常,error:{}", e);
            throw new ApiBizException(ErrorCode.OAUTH_CLIENT_QUERY_ERROR);

        }

    }

    @Override
    @Transactional
    public void deleteClient(Long clientId) {
        try {
            APIClientEntity entity = apiClientDao.selectById(clientId);
            if (null == entity) {
                return;
            }
            entity.setIsActive("N");
            entity.setIsDelete("Y");
            entity.setUpdated(new Date());

            // 删除应用，同时删除应用下的用户授权信息
            apiClientDao.updateClient(entity);
            userAuthorizationDao.deleteUserByClient(entity.getId());
        } catch (Exception e) {
            logger.error("删除应用异常,error:{}", e);
            throw new ApiBizException(ErrorCode.OAUTH_CLIENT_DELETE_ERROR);
        }

    }

    @Override
    public int checkClientCode(String clientCode) {
        Long result = apiClientDao.checkClientCode(clientCode);

        if (result == null) {
            return 0;
        }

        return result.intValue();
    }

    @Override
    public Page<APIClientVo> findByDeveloper(QueryClientByDeveloperCommand command) {

        Searchable searchable = command.getSearchable();
        if (command.getDeveloperId() != null) {
            searchable.addSearchFilter(SearchFilterHelper.newCondition("DEVELOPER_ID",
                SearchOperator.eq,
                command.getDeveloperId()));
        }
        searchable.addSearchFilter(SearchFilterHelper.newCondition("IS_DELETE", SearchOperator.eq, "N"));
        searchable.addSearchFilter(SearchFilterHelper.newCondition("IS_ACTIVE", SearchOperator.eq, "Y"));
        searchable.addSort(new Sort(Direction.DESC, "CREATED"));

        PageBase<APIClientEntity> pageBase = apiClientDao.find(searchable);
        if (null == pageBase) {
            return null;
        }
        return BeanUtils.copyPageList(pageBase, APIClientVo.class);

    }

    @Override
    public Map<String, APIClientVo> findAll() {
        try {
            List<APIClientEntity> list = apiClientDao.findAll();
            if (CollectionUtils.isEmpty(list)) {
                return null;
            }
            Map<String, APIClientVo> map = new HashMap<String, APIClientVo>();
            for (APIClientEntity entity : list) {
                APIClientVo vo = BeanUtils.copyProperties(entity, APIClientVo.class);
                map.put(vo.getClientKey(), vo);
            }

            return map;
        } catch (Exception e) {
            logger.error("查询应用列表findAll()异常,error:{}", e);
            throw new ApiBizException(ErrorCode.OAUTH_CLIENT_QUERY_ERROR);
        }
    }

}
